﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace TransportLayer.NodeLibrary
{
    //generyczne źródło ruchu, wysyłające przez swój port dane o losowej długości 
    public class Source : Cleaner
    {
        private int id;
        public int Id { get { return id; } }

        private string name;
        public string Name { get { return name; } set { name = value; } }

        private Log log;
        public Log Log { get { return log; } }

        private SourceSNP snp;
        public SourceSNP Snp { get { return snp; } }

        private string message = "";
        public string Message { get { return message; } set { message = value; } }

        private int target;
        public int Target { get { return target; } set { target = value; } }

        private Dictionary<int, RoutingEntry> targets = new Dictionary<int, RoutingEntry>();
        public Dictionary<int, RoutingEntry> Matrix { get { return targets; } }

        private int speed;
        public int Speed { set { speed = value;  } }

        private PortOut portOut; 
        public PortOut PortOut { get { return portOut; } }

        public Source(TransportLayer.Node node, int managerPort)
        {
            this.id = node.Id;
            this.name = (string)node.Name.Clone();
            this.log = new Log("Log zrodla " + Name);
            this.snp = new SourceSNP(this, managerPort);
            this.portOut = new PortOut(0);
        }

        private int maximumlength = 1000;
        public void SetMaximumLength(int len) { maximumlength = len; } //Ustawianie maxymalnej dlugosci generowanego strumieni uzytkowego
        public int GetMaximumLength() { return maximumlength; } //Zwracanie maxymalnej dlugosci generowanego strumieni uzytkowego


        public ProtocolUnit GenerateData()
        {
                RoutingEntry target = Matrix[this.Target];
                var pu = new ProtocolUnit();
                pu.Stream = target.Stream;
                pu.Put = ProtocolUnitType.NORMAL_PACKET;
                pu.Message = message;
                this.portOut.Send(pu);
                log.LogMsg("Send packet: " + target.Stream + ":0");
            return pu;
        }

        public void Send()
        {
            if (speed == 0)
                this.GenerateData();
            else
            {
                while (speed != 0)
                {
                    this.GenerateData();
                    Thread.Sleep(speed);
                }
            }
        }

        public bool Add(RoutingEntry re, int connectionID)
        {
            if (targets.ContainsKey(connectionID))
                return false;
            else
            {
                targets.Add(connectionID, re);
                return true;
            
            }
        }


        public void Clean()
        {
            portOut.Clean();
            snp.Clean();
        }

    }
}
